﻿Imports WPFGlue.Framework

Namespace Navigation

    Public Class ExpiredPage
        Inherits Adorner
        Implements IStickyComponent

        Private _Template As XDocument = <?xml version="1.0"?>
                                         <ControlTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                             xmlns:n="clr-namespace:WPFGlue.Navigation;assembly=WPFGlue"
                                             TargetType="{x:Type Control}">
                                             <Grid Background="#80FFFFFF">
                                                 <Viewbox Stretch="Uniform">
                                                     <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(n:ExpiredPage.Text)}"
                                                         Foreground="Red" FontWeight="UltraBold" Opacity="0.5">
                                                         <TextBlock.LayoutTransform>
                                                             <RotateTransform CenterX="0.5" CenterY="0.5" Angle="-45"/>
                                                         </TextBlock.LayoutTransform>
                                                     </TextBlock>
                                                 </Viewbox>
                                                 <Grid Margin="15" HorizontalAlignment="Center"
                                                     VerticalAlignment="Center">
                                                     <Border CornerRadius="3" Margin="5" BorderBrush="Black" BorderThickness="1">
                                                         <Border.Effect>
                                                             <DropShadowEffect/>
                                                         </Border.Effect>
                                                     </Border>
                                                     <Border CornerRadius="3" Margin="5" Background="White" BorderBrush="Black" BorderThickness="1"
                                                         Padding="3">
                                                         <TextBlock TextWrapping="Wrap"
                                                             TextAlignment="Center"
                                                             Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(n:ExpiredPage.Hint)}"/>
                                                     </Border>
                                                 </Grid>
                                             </Grid>
                                         </ControlTemplate>

        Private _Content As Control = New Control
        Public ReadOnly Property Content() As Control
            Get
                Return _Content
            End Get
        End Property

        Private _IsPageEnabled As Boolean

        Public Sub New(ByVal adornedElement As UIElement)
            MyBase.New(adornedElement)
            Content.Template = System.Windows.Markup.XamlReader.Load(_Template.CreateReader) 'Application.Current.FindResource("ExpiredPageTemplate") 
        End Sub

        Public ReadOnly Property Mode() As AttachMode Implements IStickyComponent.Mode
            Get
                Return AttachMode.OnLoaded
            End Get
        End Property

        Public Sub OnAttach(ByVal sender As Object, ByVal e As System.EventArgs) Implements IStickyComponent.OnAttach
            Dim page As DependencyObject = sender
            Dim parent As DependencyObject = LogicalTreeHelper.GetParent(page)
            If parent IsNot Nothing Then
                Dim text As String = GetText(parent)
                Dim template As ControlTemplate = GetTemplate(parent)
                Dim hint As String = GetHint(parent)
                If text IsNot Nothing Then
                    SetText(Content, text)
                End If
                If template IsNot Nothing Then
                    Content.Template = template
                End If
                If hint IsNot Nothing Then
                    SetHint(Content, hint)
                End If
            End If
            Dim al As AdornerLayer = AdornerLayer.GetAdornerLayer(sender)
            If al IsNot Nothing Then
                al.Add(Me)
            End If
            _IsPageEnabled = page.GetValue(UIElement.IsEnabledProperty)
            page.SetValue(UIElement.IsEnabledProperty, False)
            Dim service As NavigationService = NavigationService.GetNavigationService(sender)
            If service IsNot Nothing Then
                AddHandler service.Navigating, AddressOf OnExpiredNavigating
            End If
        End Sub

        Public Sub OnDetach(ByVal sender As Object, ByVal e As System.EventArgs) Implements IStickyComponent.OnDetach
            Dim al As AdornerLayer = AdornerLayer.GetAdornerLayer(sender)
            If al IsNot Nothing Then
                al.Remove(Me)
            End If
            Dim page As DependencyObject = sender
            page.SetValue(FrameworkElement.IsEnabledProperty, _IsPageEnabled)
        End Sub

        Private Shared Sub OnExpiredNavigating(ByVal sender As Object, ByVal e As NavigatingCancelEventArgs)
            Dim service As NavigationService = Navigation.GetNavigationService(sender)
            If service IsNot Nothing Then
                RemoveHandler service.Navigating, AddressOf OnExpiredNavigating
            End If
            e.ContentStateToSave = New ExpiredContentState(e.ContentStateToSave)
        End Sub

        Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.RegisterAttached("Text", GetType(String), GetType(ExpiredPage), New PropertyMetadata("Expired"))
        Public Shared Function GetText(ByVal d As DependencyObject) As String
            Return d.GetValue(TextProperty)
        End Function
        Public Shared Sub SetText(ByVal d As DependencyObject, ByVal value As String)
            d.SetValue(TextProperty, value)
        End Sub

        Public Shared ReadOnly HintProperty As DependencyProperty = DependencyProperty.RegisterAttached("Hint", GetType(String), GetType(ExpiredPage), New PropertyMetadata("This page is expired. Please use Back or Forward to navigate to a different page."))
        Public Shared Function GetHint(ByVal d As DependencyObject) As String
            Return d.GetValue(HintProperty)
        End Function
        Public Shared Sub SetHint(ByVal d As DependencyObject, ByVal value As String)
            d.SetValue(HintProperty, value)
        End Sub

        Public Shared ReadOnly TemplateProperty As DependencyProperty = DependencyProperty.RegisterAttached("Template", GetType(ControlTemplate), GetType(Navigation))
        Public Shared Function GetTemplate(ByVal d As DependencyObject) As ControlTemplate
            Return d.GetValue(TemplateProperty)
        End Function
        Public Shared Sub SetTemplate(ByVal d As DependencyObject, ByVal value As ControlTemplate)
            d.SetValue(TemplateProperty, value)
        End Sub

        Protected Overrides Function MeasureOverride(ByVal constraint As System.Windows.Size) As System.Windows.Size
            Content.Measure(constraint)
            Return constraint
        End Function

        Protected Overrides Function ArrangeOverride(ByVal finalSize As System.Windows.Size) As System.Windows.Size
            Content.Arrange(New Rect(0, 0, finalSize.Width, finalSize.Height))
            Return finalSize
        End Function

        Protected Overrides ReadOnly Property VisualChildrenCount() As Integer
            Get
                Return 1
            End Get
        End Property

        Protected Overrides Function GetVisualChild(ByVal index As Integer) As System.Windows.Media.Visual
            If index = 0 Then
                Return Content
            Else
                Return Nothing
            End If
        End Function

        <Serializable()> _
        Public Class ExpiredContentState
            Inherits CustomContentState

            Private _PreviousState As CustomContentState
            Public Sub New(ByVal previousState As CustomContentState)
                MyBase.New()
                _PreviousState = previousState
            End Sub
            Public Overrides Sub Replay(ByVal navigationService As System.Windows.Navigation.NavigationService, ByVal mode As System.Windows.Navigation.NavigationMode)
                If _PreviousState IsNot Nothing Then
                    _PreviousState.Replay(navigationService, mode)
                End If
                Navigation.SetIsExpired(navigationService.Content, True)
                Validation.Validation.SetSuppressErrorTemplate(navigationService.Content, True)
                AddHandler navigationService.Navigating, AddressOf OnExpiredNavigating
            End Sub
        End Class
    End Class

End Namespace
